package mauth

import (
	"github.com/gin-gonic/gin"
	"mygo/mymongo"
	"mygo/mystruct"
	"fmt"
	"strings"
	"regexp"
)

// 数据表权限认证
func Auth_data() gin.HandlerFunc {
	return func(c *gin.Context) {
		var codeargs string
		switch c.Request.Method {
			case "POST":
				contentType := c.ContentType()
		        if contentType == "application/json" {
		            // 从 Query 参数获取 code
		            codeargs = c.Query("code")
		        } else {
		            // 默认从 PostForm 获取（form-data / x-www-form-urlencoded）
		            codeargs = c.PostForm("code")
		        }
			case "GET": 
				codeargs = c.Query("code")
		}

		checkUnauthorized := func(errMessage string) {
			c.JSON(mystruct.StatusUnauthorized, gin.H{"error": errMessage})
			c.Abort()
		}

		Muserboot := Get_token(c)
		if Muserboot == nil {
			return
		}
		_, Body := mymongo.Auth_api_edit("", Muserboot, &mystruct.Retdate{}, codeargs)
		if Body == nil {
			checkUnauthorized("表不存在")
			return
		}
		bot_type := Get_auth(Muserboot, Body)
		switch c.Request.URL.Path {
			case "/api/append", "/api/appendall":
				if !bot_type.Add {
					checkUnauthorized("添加权限不足")
					return
				}
			case "/api/update", "/api/upfield":
				if !bot_type.Set {
					checkUnauthorized("修改权限不足")
					return
				}
			case "/api/delete", "/api/deleteall":
				if !bot_type.Del {
					checkUnauthorized("删除权限不足")
					return
				}
			case "/api/wacth", "/api/wacthid":
				if !bot_type.See {
					checkUnauthorized("查看权限不足")
					return
				}
			case "/api/word", "/api/code":
				if c.Request.Method == "GET" && !bot_type.See {
					checkUnauthorized("查看权限不足")
					return
				}
				if c.Request.Method == "POST" && !bot_type.Set {
					checkUnauthorized("修改权限不足")
					return
				}
			case "/api/pack":
				switch c.PostForm("model") {
					case mystruct.PACK_ALL:
						if !bot_type.See {
							checkUnauthorized("查看权限不足")
							return
						}
					case mystruct.PACK_CREATE_FILE, mystruct.PACK_CREATE_DIR, mystruct.PACK_UPLOAD_FILE:
					    if !bot_type.Add {
					        checkUnauthorized("添加权限不足")
					        return
					    }
					case mystruct.PACK_DELETE_DIR, mystruct.PACK_DELETE_FILE:
						if !bot_type.Del {
					        checkUnauthorized("删除权限不足")
					        return
					    }
					case mystruct.PACK_RENAME:
						if !bot_type.Set {
							checkUnauthorized("修改权限不足")
							return
						}
				}
				
			default:
				if Muserboot.Standing < mystruct.AUTH_Administrator + 1 {
					checkUnauthorized(fmt.Sprintf("路由 [ %s ] 未匹配，默认检查权限不足", c.Request.URL.Path))
					return
				}
		}
		if Body.Account != Muserboot.Account && Muserboot.Standing < mystruct.AUTH_Administrator + 1 {
			clientIP := GetClientIP(c)
			for _, restrictedIP := range strings.Split(Body.Ipblacklist, ";") {
            	var ret bool
            	if strings.Contains(restrictedIP, "*") {
			        restrictedIP = strings.ReplaceAll(restrictedIP, ".", "\\.")
			        restrictedIP = strings.ReplaceAll(restrictedIP, "*", "\\d+")
			        ret = regexp.MustCompile("^" + restrictedIP + "$").MatchString(clientIP)
			    }else{
			        ret = restrictedIP == clientIP
			    }
			    if ret {
					checkUnauthorized("IP被禁止")
					return
			    }
        	}
		}
		c.Next()
	}
}

// api表权限认证
func Auth_api() gin.HandlerFunc {
	return func(c *gin.Context) {
		mpath := c.Request.URL.Path
		Muserboot := Get_token(c)
		if Muserboot == nil {
			return
		}
		checkUnauthorized := func(errMessage string) {
			c.JSON(mystruct.StatusUnauthorized, gin.H{"error": errMessage})
			c.Abort()
		}

		if mpath == "/api/addapi" {
			if Muserboot.Standing < mystruct.AUTH_User + 1 {
				checkUnauthorized("权限不足")
				return
			}
		}else{
			results := &mystruct.Retdate{"authMiddleware_api", mystruct.MyCodeOk, "succeed"}
			_, Body := mymongo.Auth_api_edit("", Muserboot, results, c.PostForm("apiid"))
			if Body == nil {
				checkUnauthorized("表不存在")
				return
			}
			switch mpath {
				case "/api/delapi":
					if results.Code != mystruct.MyCodeOk {
						checkUnauthorized(results.Mesg)
						return
					}
				case "/api/setapi":
					if results.Code != mystruct.MyCodeOk {
						checkUnauthorized(results.Mesg)
						return
					}
				case "/api/getapi":
					bot_type := Get_auth(Muserboot, Body)
					if !bot_type.See {
						checkUnauthorized("权限不足")
						return
					}
				default:
					if Muserboot.Standing < mystruct.AUTH_Superadmin + 1 {
						checkUnauthorized(fmt.Sprintf("路由 [ %s ] 未匹配，默认检查权限不足", mpath))
						return
					}
			}
		}
		c.Next()
	}
}

// 权限获取
func Get_auth(Muserboot *mystruct.Muser, codb *mystruct.ModelItem) mystruct.Mroute {
	if Muserboot.Standing > mystruct.AUTH_Superadmin {
		return mystruct.Mroute{true, true, true, true}
	}
	var bot_type mystruct.Mroute 
	bot_type, ok := Muserboot.Authority[codb.Apiid]
	if !ok {
		switch {
			case Muserboot.Standing < mystruct.AUTH_Tourist + 1:
				bot_type = codb.Authority.Visitor

			case mystruct.AUTH_Tourist < Muserboot.Standing && Muserboot.Standing < mystruct.AUTH_User + 1:
				bot_type = codb.Authority.User

			case mystruct.AUTH_User < Muserboot.Standing && Muserboot.Standing < mystruct.AUTH_Administrator + 1:
				bot_type = codb.Authority.Root

			case mystruct.AUTH_Administrator < Muserboot.Standing && Muserboot.Standing < mystruct.AUTH_Superadmin + 1:
				bot_type = mystruct.Mroute{true, true, true, true}

			default:
				bot_type = mystruct.Mroute{false, false, false, true}
		}
	}
	return bot_type
}